package com.qf.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.POJO.Users;
import com.qf.utils.JWTUtils;
import com.qf.utils.R;
import com.qf.utils.RsaUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.ResourceUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.PublicKey;
import java.util.List;

/**
 * 1.创建令牌认证过滤器继承BasicAuthenticationFilter
 * 2.创建带AuthenticationManager参数构造器
 * 3.重写doFilterInternal自定义jwt令牌认证实现
 */
public class JwtVerifyFilter extends BasicAuthenticationFilter {
    public JwtVerifyFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        //1.过滤器默认会拦截所有请求，需要放行登录请求
        if("/user/login".equals(request.getRequestURI())){
            chain.doFilter(request,response);
            return;
        }

        //2放行预检请求
        String method = request.getMethod();
        if("OPTIONS".equalsIgnoreCase(method)){
            return;
        }

        //3.从请求头获取jwt token令牌
        String token = request.getHeader("token");
        if(token == null){
            R r = R.fail().code("1").desc("token令牌为空");
            doResponse(response,r);
            return;
        }

        //4.校验令牌是否合法
        PublicKey publicKey = null;
        try {

            byte[] keyBytes = RsaUtils.readFile("pub.txt");
            publicKey = RsaUtils.getPublicKey(keyBytes);
            Users user = (Users) JWTUtils.getInfoFromToken(token,publicKey, Users.class);
            String roleStr = user.getRoleStr();
            String perStr = user.getPerStr();
            //5.将用户信息封装成为UsernamePasswordAuthenticationToken存到securityContext
            List<GrantedAuthority>roleAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(roleStr);
            List<GrantedAuthority>perAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(perStr);
            roleAuthorities.addAll(perAuthorities);
            UsernamePasswordAuthenticationToken authenticationToken
                    = new UsernamePasswordAuthenticationToken(user,null,roleAuthorities);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            //6.放行
            chain.doFilter(request,response);
        } catch (Exception e){
            doResponse(response,R.fail().code("1").desc("权限为空"));
        }
    }

    private void doResponse(HttpServletResponse response, R r) throws IOException {
        String jsonStr = new ObjectMapper().writeValueAsString(r);
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json");
        PrintWriter writer = response.getWriter();
        writer.print(jsonStr);
        writer.flush();
        writer.close();
    }

}